import hashlib
import json
import time
import urllib.request
from urllib.parse import urlencode


class ApiTools:
    def __init__(self, url, secret_key, data):
        """
        API接口工具
        :param url: 接口地址
        :param secret_key: API安全密钥
        :param data: 原始数据
        """
        self.url = url
        self.secret_key = secret_key
        self.data = data

    def sign(self):
        """
        对原始数据进行签名
        :return: 返回自身以支持链式调用
        """
        # 为数据追加时间戳和API安全密钥
        self.data["timeStamp"] = self.__get_time_stamp()
        self.data["secretKey"] = self.secret_key
        # 追加签名
        self.data["sign"] = self.__get_sign()
        # 移除API安全密钥
        self.data.pop("secretKey")
        # 返回自身以支持链式调用
        return self

    def send(self):
        """
        发送请求
        :return: 服务器的响应
        """
        # 请求头
        headers = {
            "Content-Type": "application/json"
        }
        # 请求数据
        data = bytes(json.dumps(self.data), 'utf-8')
        # 创建请求
        request = urllib.request.Request(self.url, headers=headers, data=data)
        # 获取响应
        response = urllib.request.urlopen(request)
        return response.read().decode('utf-8')

    def __get_sign(self):
        """
        [私有]根据原始数据获得签名
        :return: 经计算的签名
        """
        sorted_list = sorted(self.data.items())
        # 拼接URL结构字符串
        temp = []
        for item in sorted_list:
            temp.append(item[0] + "=" + str(item[1]))
        url = "&".join(temp)

        url = urlencode({"a": url}, encoding="utf-8")[2:]
        # MD5加密
        return hashlib.md5(url.encode(encoding='UTF-8')).hexdigest()

    def __get_time_stamp(self):
        """
        获取当前时间戳（毫秒级）
        :return: 当前时间戳（毫秒级）
        """
        return int(round((time.time()-60) * 1000))
